package com.ruicar.afs.cloud.workflow.greatwall.processor.impl.objcode;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.dynamicrequest.DynamicRequest;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.components.datadicsync.DicHelper;
import com.ruicar.afs.cloud.components.datadicsync.dto.DicDataDto;
import com.ruicar.afs.cloud.workflow.api.dto.FlowParam;
import com.ruicar.afs.cloud.workflow.greatwall.dto.GwtRequest;
import com.ruicar.afs.cloud.workflow.greatwall.dto.design.ConfigParamDto;
import com.ruicar.afs.cloud.workflow.greatwall.entity.AfsGreatWallFlowParams;
import com.ruicar.afs.cloud.workflow.greatwall.enums.GwtMsgType;
import com.ruicar.afs.cloud.workflow.greatwall.enums.GwtObjectCode;
import com.ruicar.afs.cloud.workflow.greatwall.processor.AbsBaseProcessor;
import com.ruicar.afs.cloud.workflow.greatwall.processor.GwfObjectCodeProcessor;
import com.ruicar.afs.cloud.workflow.greatwall.service.AfsGreatWallFlowParamsService;
import com.ruicar.afs.cloud.workflow.greatwall.service.AfsGreatWallWorkflowBizDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * The type GwfConfigParamProcessor
 * <p>Description: </p>
 *
 * @author Fzero
 * @version 1.0
 * @date Created on 2020.07.10 21:22:46
 * @since 1.0
 */
@Component
@Slf4j
public class GwfConfigParamProcessor extends AbsBaseProcessor implements GwfObjectCodeProcessor {
    /**
     * Afs great wall flow params service
     * <p>Description: </p>
     */
    private final AfsGreatWallFlowParamsService afsGreatWallFlowParamsService;
    /**
     * Dynamic request
     * <p>Description: </p>
     */
    private final DynamicRequest dynamicRequest;

    /**
     * Gwf config param processor
     *
     * @param afsGreatWallWorkflowBizDataService afs great wall workflow biz data service
     * @param afsGreatWallFlowParamsService      afs great wall flow params service
     * @param dynamicRequest                     dynamic request
     */
    public GwfConfigParamProcessor(AfsGreatWallWorkflowBizDataService afsGreatWallWorkflowBizDataService, AfsGreatWallFlowParamsService afsGreatWallFlowParamsService, DynamicRequest dynamicRequest) {
        super(afsGreatWallWorkflowBizDataService);
        this.afsGreatWallFlowParamsService = afsGreatWallFlowParamsService;
        this.dynamicRequest = dynamicRequest;
    }

    /**
     * Belong msg gwt msg type
     *
     * @return the gwt msg type
     */
    @Override
    public GwtMsgType belongMsg() {
        return GwtMsgType.FLOW_DESIGN;
    }

    /**
     * Object code gwt object code
     *
     * @return the gwt object code
     */
    @Override
    public GwtObjectCode objectCode() {
        return GwtObjectCode.DESIGN_FLOW_PARAM_CONFIG_INFO;
    }

    /**
     * Process string
     *
     * @param request request
     * @return the string
     */
    @Override
    public String process(GwtRequest request) {
        log.info("{}", request);
        JSONArray rtnJson = new JSONArray();
        List<AfsGreatWallFlowParams> afsGreatWallFlowParamsList = afsGreatWallFlowParamsService.
                list(Wrappers.<AfsGreatWallFlowParams>lambdaQuery().eq(AfsGreatWallFlowParams::getGreatWallServiceId, request.getServiceId()));
        afsGreatWallFlowParamsList.stream()
                .forEach(param -> {
                    rtnJson.add(processParam(param));
                });
        return rtnJson.toJSONString();
    }

    /**
     * Process param config param dto
     *
     * @param param param
     * @return the config param dto
     */
    private ConfigParamDto processParam(AfsGreatWallFlowParams param) {
        ConfigParamDto configParamDto = new ConfigParamDto(param.getParamName(), param.getParamKey());
        configParamDto.setType(param.getGwFlowParamType());
        JSONObject configInfo = JSON.parseObject(param.getParamConfig());
        switch (param.getParamType()) {
            case DIC:
                configParamDto.setOption(new ArrayList<>());
                DicHelper.getDicMaps(configInfo.getString("dicKey")).forEach((key, value) -> {
                    value.stream().forEach(dicDataDto -> {
                        configParamDto.getOption().add(new FlowParam(dicDataDto.getTitle(), dicDataDto.getValue()) {
                        });
                    });
                });
                break;
            case CUSTDIC:
                configParamDto.setOption(new ArrayList<>());
                IResponse<List<DicDataDto>> response = null;
                if ("post".equalsIgnoreCase(configInfo.getString("method"))) {
                    response = dynamicRequest.post(configInfo.getString("serviceName"), configInfo.getString("uri"), configInfo.getJSONObject("params"), new TypeReference<List<DicDataDto>>() {
                    });
                } else if ("get".equalsIgnoreCase(configInfo.getString("method"))) {
                    Map<String, String> map = new HashMap<>();
                    configInfo.getJSONObject("params")
                            .keySet()
                            .stream()
                            .forEach(key -> map.put(key, configInfo.getJSONObject("params").getString(key)));
                    response = dynamicRequest.get(configInfo.getString("serviceName"), configInfo.getString("uri"), map, new TypeReference<List<DicDataDto>>() {
                    });
                } else {
                    log.warn("未知类型请求{}", JSON.toJSONString(param));
                }
                if (response != null && CommonConstants.SUCCESS.equalsIgnoreCase(response.getCode())) {
                    response.getData().stream().forEach(dicDataDto -> {
                        configParamDto.getOption().add(new FlowParam(dicDataDto.getTitle(), dicDataDto.getValue()) {
                        });
                    });
                } else {
                    log.warn("自定义字典获取失败{}", JSON.toJSONString(param));
                }
                break;
            case AREA:
            case CASCADER:
            default:
                break;
        }
        return configParamDto;
    }
}
